package com.net;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.StringTokenizer;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

import com.bean.UpdateBean;
import com.constant.Constant;

import edu.xhu.util.secret;

public class XiaoYuan {
	private static final int REQUEST_TIMEOUT = 10*1000;
	private static final int SO_TIMEOUT = 10*1000; 
	
	public static boolean phoneResponse(String Imei,String content) throws ClientProtocolException, IOException, XmlPullParserException{
		String params = createXMLForPhoneResponse(Imei,content);
		params = str_replace("=","%~%",params);
		InputStream in = null;
		DataOutputStream dos = null; 
		URL realUrl = new URL(Constant.HOST + "phoneResponse");
//		System.out.println("real_Url="+realUrl);
		URLConnection conn = realUrl.openConnection();
		conn.setConnectTimeout(5000); 
		
		conn.setReadTimeout(5000); 
		conn.setRequestProperty("accept", "*/*");
		conn.setRequestProperty("connection", "Keep-Alive");
		conn.setRequestProperty("user-agent",
			"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
		conn.setDoOutput(true);
		conn.setDoInput(true);
		dos = new DataOutputStream(conn.getOutputStream()); 
		dos.write(params.getBytes());
		dos.flush(); 
		in = conn.getInputStream();  
		return  analyzeInputStreamToBoolean(in, "phoneResponse"); 
	}
	
	 
	public static void sendStatistics(String Imei, String channle, String per_count) throws ClientProtocolException, IOException, XmlPullParserException{
		sendRequestToServer("sendStatistics/"+Imei+"/"+channle+"/"+per_count);
	}
		
	
	
	public static UpdateBean getUpdateInfo() throws ClientProtocolException, IOException, XmlPullParserException{
		InputStream is = sendRequestToServer("getUpateInfo");
		return analyzeInputStreamToUpdateInfo(is);
	}
 
	/*xmlSerializer:将对象序列化到 XML 文档中和从 XML 文档中反序列化对象。XmlSerializer 使您得以控制如何将对象编码到 XML 中。
	 * Serialize这个单词的意思是：序列化*/
	
	/*Writer和Reader类是设计来处理基于字符串的输入和输出的。
	 * InputStream和OutputStream类则应该用于处理基于字节的I/O。
	 * 在这个层次的类中，可以用ByteArrayInputStream和ByteArrayOutputStream来达到StringReader和StringWriter的类似效果。*/
	
	//函数主要目的：把Imei,content这两个参数所对应的字符串转换为XML。
	public static String createXMLForPhoneResponse(String Imei,String conent){
		StringWriter xmlWriter = new StringWriter();
		  try {
		   XmlPullParserFactory pullParserFactory = XmlPullParserFactory.newInstance();
		   XmlSerializer xmlSerializer = pullParserFactory.newSerializer();
		   xmlSerializer.setOutput(xmlWriter);// 设置输出流对象 
		   xmlSerializer.startDocument("UTF-8", true);
		   /* startDocument(String encoding, Boolean standalone)encoding代表编码方式 
			   * standalone  用来表示该文件是否呼叫其它外部的文件。 
			   * 若值是 ”yes” 表示没有呼叫外部规则文件，若值是 ”no” 则表示有呼叫外部规则文件。默认值是 “yes”。 
			   */ 
		   xmlSerializer.startTag("", "phoneResponse"); 
		   String text ; 
		   		text = secret.encodeToString(Imei.getBytes(), 0);
			    xmlSerializer.startTag("", "Imei");
			    /* 
			   * startTag (String namespace, String name)这里的namespace用于唯一标识xml标签 
			    *XML 命名空间属性被放置于某个元素的开始标签之中，并使用以下的语法： 
			    *xmlns:namespace-prefix="namespaceURI" 
			    *当一个命名空间被定义在某个元素的开始标签中时，所有带有相同前缀的子元素都会与同一个命名空间相关联。 
			    *注释：用于标示命名空间的地址不会被解析器用于查找信息。其惟一的作用是赋予命名空间一个惟一的名称。
			    *不过，很多公司常常会作为指针来使用命名空间指向某个实存的网页，这个网页包含着有关命名空间的信息。 
			    */  
			    xmlSerializer.text(text);
			    xmlSerializer.endTag("", "Imei"); 
		   		text = secret.encodeToString(conent.getBytes(), 0);
			    xmlSerializer.startTag("", "content");
			    xmlSerializer.text(text);
			    xmlSerializer.endTag("", "content");
 
		    xmlSerializer.endTag("", "phoneResponse");
		    xmlSerializer.endDocument();
		  }
		  catch(Exception ex) {
		   ex.printStackTrace();
		  }
//		  Log.e("xml", "xml:"+xmlWriter.toString());
		  return xmlWriter.toString();
	}
	
	
	
	public static boolean confirmDeal(String username,int Trade_ID) throws ClientProtocolException, IOException, XmlPullParserException{
		InputStream is = sendRequestToServer("confirmDeal/"+username+"/"+Trade_ID);//向服务器发送一个请求
		return  analyzeInputStreamToBoolean(is,"isconfirmDeal");//发送该<isconfirmDeal><isconfirmDeal>中间为ture或者为false
	}
	
	/*UpdateBean记录本版本的信息和下载信息，在本类中有如下三个属性：
	 * 	String version;//版本号
	    String url_apk;//下载地址
	    String description;//说明*/
	//本函数的作用是：分解传入进来的InputStream，得到一个UpdateBean
	//分析方法还是使用XmlPullParse
	private static UpdateBean analyzeInputStreamToUpdateInfo(InputStream is) throws XmlPullParserException, IOException {
	 	  XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
		  factory.setNamespaceAware(true);
		  XmlPullParser parser = factory.newPullParser();
		  parser.setInput(is, "UTF-8"); 
		  UpdateBean info = new UpdateBean(); 
		  for(int i = parser.getEventType(); i != XmlPullParser.END_DOCUMENT; i = parser.next())
		  {
			 if(i == XmlPullParser.START_TAG && parser.getName().equals("version"))
			 { 
				 info.setVersion(parser.nextText());
				 continue;
			 }
			 if(i == XmlPullParser.START_TAG && parser.getName().equals("apk_url"))
			 {
				 info.setUrl_apk(parser.nextText()); 
				 continue;
			 }
			 if(i == XmlPullParser.START_TAG && parser.getName().equals("description"))
			 {
				 info.setDescription(parser.nextText());
				 continue;
			 }  
		  }
		 return info; 
	}
	
	/*StringTokenizer类的作用是分解字符串，本函数中使用到的方法为:
	 * StringTokenizer(String string, String delimiters, boolean returnDelimiters)
	 * 意思是在string字符串中以delimiters为分解符分解，第三个参数如果为true，则返回分解符，
	 * 如果为false则不返回分解符。
    */

	//本函数的作用是：在source字符串中，将所有的form对应的字符串，转变为to对应的字符串
	 public static String str_replace(String from,String to,String source) {
	     StringBuffer bf= new StringBuffer("");
	     StringTokenizer st = new StringTokenizer(source,from,true);
	     while (st.hasMoreTokens()) {
	       String tmp = st.nextToken();
	       if(tmp.equals(from)) {
	         bf.append(to);
	       } else {
	         bf.append(tmp);
	       }
	     }
	     return bf.toString();
	   }


	//XmlPullParser是指Xml解析器，有两个关键方法：next()和nextToken()
	    //其中next()提供了高水平的解析事件，nextToken()提供了低水平的解析事件
	    //getEventType()可以获得当前事件状态，初始为START_DOCUMENT
	    //next()的方法推动解析到下一个事件
	 /*START_TAG 一个XML开始标记读取 
	  * TEXT 文本内容被阅读;
	  * 文本内容可以检索使用getText()方法。
	  * (当在验证模式下next()将不会报告可忽略的空格,使用nextToken()而不是) 
     END_TAG 一个结束标记被读取 
     END_DOCUMENT 没有更多的事件是可用*/
	 /*有例子如下：xpp.setInput( new StringReader ( "<foo>Hello World!</foo>" ) );  
	 19.         int eventType = xpp.getEventType();  
	 20.         while (eventType != XmlPullParser.END_DOCUMENT) {  
	 21.          if(eventType == XmlPullParser.START_DOCUMENT) {  
	 22.              System.out.println("Start document");  
	 23.          } else if(eventType == XmlPullParser.START_TAG) {  
	 24.              System.out.println("Start tag "+xpp.getName());  
	 25.          } else if(eventType == XmlPullParser.END_TAG) {  
	 26.              System.out.println("End tag "+xpp.getName());  
	 27.          } else if(eventType == XmlPullParser.TEXT) {  
	 28.              System.out.println("Text "+xpp.getText());  
	 29.          }  
	 30.          eventType = xpp.next();  
	 31.         }  
	 32.         System.out.println("End document");  
	 */
	 /*最后输出：	1.Start document  
   	2. Start tag foo  
		3. Text Hello World!  
		4. End tag foo  
		5. End document 
*/

	    public static boolean analyzeInputStreamToBoolean(InputStream is,String name_Zone) throws XmlPullParserException, IOException{
			XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
			factory.setNamespaceAware(true);//设置该解析器工厂出来的解析器支持命名空间
			XmlPullParser parser = factory.newPullParser();
			parser.setInput(is, "UTF-8");
			for(int i = parser.getEventType(); i != XmlPullParser.END_DOCUMENT; i = parser.next()) {
				if(i == XmlPullParser.START_TAG && parser.getName().equals(name_Zone)){
					//文件头的名字等于name_Zone时，如<name_Zone>true<name_Zone>
					String next = parser.nextText();//取出头文件后面的数据，如果等于“true”则返回true，不等于“true”则返回false 
					if(next.equals("true")){ 
						return true;
					}else{
						return false;
					}
				}
			}
			return false;
	    }
	    
	  //函数作用：发送请求到服务器，得到服务器的回复
	    //返回InputStream
	    //这里的HOST = "http://www.esjiaoyi.com/index.php/server/"
		public static InputStream sendRequestToServer(String message_string) throws ClientProtocolException, IOException{
			HttpClient client = getHttpClient();
			String url =   Constant.HOST + message_string;
			HttpPost request = new HttpPost(url);
			HttpResponse http_response = client.execute(request);
			HttpEntity entity = http_response.getEntity();
			InputStream inStream = entity.getContent();
			return inStream;
		} 

		//函数作用返回一个HttpClient对象，设置它的一些参数
		//如ConnectionTimeout=10000，和SoTimeout=10000。
		public static HttpClient getHttpClient(){ 
		    BasicHttpParams httpParams = new BasicHttpParams(); 
		    HttpConnectionParams.setConnectionTimeout(httpParams, REQUEST_TIMEOUT); 
		    HttpConnectionParams.setSoTimeout(httpParams, SO_TIMEOUT); 
		    HttpClient client = new DefaultHttpClient(httpParams); 
		    return client; 
		}

}
